const store = {}; // 用于存储状态
const subscribers = new Map();
export const createStore = () => {
  const sharedState = new Proxy(store, {
    get: function (target, key) {
      return target[key];
    },
    set: function (target, key, value) {
      if (
        Object.prototype.toString.call(value) === "[object Object]" &&
        value !== null
      ) {
        value = createObjectProxy(value, `${key}.`);
      }
      if (
        Object.prototype.toString.call(value) === "[object Array]" &&
        value !== null
      ) {
        // 对数组类型对象进行特殊处理
        value = createArrayProxy(value, `${key}.`);
      }

      let result = Reflect.set(target, key, value);
      // 发送通知，更新所有组件中对应key的值
      updateAllComponents(key, value);
      return result;
    },
  });
  function createObjectProxy(target, path = "") {
    return new Proxy(target, {
      set(obj, prop, val) {
        const result = Reflect.set(obj, prop, val);
        // 发送通知，更新所有组件中对应key的值
        const parentKey = path.replace(".", "");
        updateAllComponents(`${path}${prop}`, val);
        // 发送通知，更新父类组件中对应key的值
        updateAllComponents(parentKey, obj);
        return result;
      },
      get(target, key) {
        const value = Reflect.get(target, key);
        // 如果 value 是对象，则为其继续创建代理
        if (
          Object.prototype.toString.call(value) === "[object Object]" &&
          value !== null
        ) {
          return createObjectProxy(value, `${path}${key}.`);
        }
        return value;
      },
    });
  }
  function createArrayProxy(target, path = "") {
    return new Proxy(target, {
      get(target, prop, receiver) {
        return Reflect.get(target, prop, receiver);
      },
      set(target, prop, val) {
        const result = Reflect.set(target, prop, val);
        if (typeof prop === "string" && /^\d+$/.test(prop)) {
          const index = parseInt(prop);
          const length = target.length || 0;
          if (index >= length) {
            target.length = index + 1;
          }
          updateAllComponents(path.slice(0, -1), target);
        }
        return result;
      },
      has(target, prop) {
        if (typeof prop === "string" && /^\d+$/.test(prop)) {
          const index = parseInt(prop);
          return index < target.length;
        }
        return prop in target;
      },
    });
  }

  function subscribe(key, callback) {
    if (!subscribers.has(key)) {
      subscribers.set(key, new Set());
    }
    subscribers.get(key).add(callback);
    console.log("subscribers", subscribers);
  }
  function unsubscribe(key, callback) {
    const subscribersSet = subscribers.get(key);
    if (subscribersSet) {
      subscribersSet.delete(callback);
      if (subscribersSet.size === 0) {
        subscribers.delete(key);
      }
    }
  }
  function publish(key, value) {
    if (subscribers.has(key)) {
      for (let callback of subscribers.get(key)) {
        callback(value);
      }
    }
  }
  function updateAllComponents(key, value) {
    publish(key, value);
  }
  return {
    store: sharedState,
    subscribe,
    unsubscribe,
  };
};
